package b.cif.impl

import akka.NotUsed
import b.cif.api._
import b.utils.api.T底层Service
import com.lightbend.lagom.scaladsl.api.ServiceCall
import com.lightbend.lagom.scaladsl.api.transport.NotFound
import com.lightbend.lagom.scaladsl.persistence.cassandra.CassandraSession
import com.lightbend.lagom.scaladsl.persistence.{PersistentEntityRef, PersistentEntityRegistry, ReadSide}

import scala.concurrent.{ExecutionContext, Future}

class C客户ServiceImpl(
  registry: PersistentEntityRegistry,
  readSide: ReadSide,
  db: CassandraSession,
  utils: T底层Service)(implicit ex: ExecutionContext) extends T客户Service {

  val v集群号 = 1
  assert(v集群号 < 10)
  val v机器号 = 1
  assert(v机器号 < 100)

  override def f开客户(): ServiceCall[CC开客户Request, String] = ServiceCall { v请求 =>
    val ref = refBy(v请求.v证件.toString)
    ref.ask(CC客户GetCommand()).flatMap {
      case Some(v客户) => Future.successful(v客户.v客户号)
      case None =>
        val cno = registry.refFor[C客户号PersistentEntity](s"/$v集群号/$v机器号")
        val v客户序号 = cno.ask(CC申请客户号Command())
        v客户序号.flatMap { x客户序号: Int =>
          val v客户号 = v集群号.toString + "%02d".format(v机器号) + "%07d".format(x客户序号)
          val v客户 = CC客户(v客户号, v请求.v证件, v请求.v户名)
          ref.ask(CC开客户Command(v客户))
            .map { _ => v客户号 }
        }
    }
  }
  override def f取账户序号(v客户号: String): ServiceCall[NotUsed, Int] = ServiceCall { _ =>
    refFor(v客户号).flatMap { ref =>
      ref.ask(CC申请账号Command())
    }
  }
  override def f客户查询(v客户号: String): ServiceCall[NotUsed, CC客户] = ServiceCall { _ =>
    refFor(v客户号).flatMap { ref =>
      ref.ask(CC客户GetCommand())
        .map(_.getOrElse(throw NotFound(s"客户[$v客户号]")))
    }
  }
  private[this] def refBy(entityId: String): PersistentEntityRef[T客户Command] =
    registry.refFor[C客户PersistentEntity](s"/$entityId")
  private[this] def refFor(v客户号: String): Future[PersistentEntityRef[T客户Command]] = {
    db.selectOne(s"SELECT no, id, idType FROM customer WHERE no = '$v客户号'")
      .map { r =>
        val row = r.getOrElse(throw NotFound(s"客户[$v客户号]"))
        refBy(row.getString("id") + "-" + row.getString("idType"))
      }
  }

}
